\- Latch : SGA내의 자료구조를 보호할 목적으로 사용, SGA 내부에서만 사용되며, 큐로 관리 되지 않음
\- Lock : Table, Data Block 등의 Object를 보호할 목적으로 사용, 큐로 관리됨
: Table, Transaction, Tablespace, Sequence, Temporary Segment 등과 같은 Resource 대한 Access를 관리하는 Lock, 큐로 관리됨
=> Type
TX : Transaction에 의한 DML Row Lock
TM : DML Table Lock
TS : Temp Access Lock
=> ID1, ID2
Lock 종류별 정보
SQL> select type, id1_tag,id2_tag,name, description from v$lock_type where type in ('TM','TX','TS');
TYPE ID1_TAG ID2_TAG NAME DESCRIPTION
---------- --------------- ------------------------- -------------------- --------------------------------------------------
TM object # table/partition DML Synchronizes accesses to an object
TS tablespace ID dba Temporary Segment Serializes accesses to temp segments
TX usn<<16 | slot sequence Transaction Lock held by a transaction to allow other transact
ions to wait for it
- v$lock_type : Lock의 유형별 설명 (10g 이상) -
ex)
SQL> select type, name, description from v$lock_type;
TYPE NAME DESCRIPTION
---------- -------------------------------------------------- --------------------------------------------------
KM Scheduler Synchronizes various Resource Manager operations
KT Scheduler Plan Synchronizes accesses to the current Resource Mana
ger plan
CI Cross-Instance Call Invocation Coordinates cross-instance function invocations
PR Process Startup Synchronizes process startup
AK GES Deadlock Test Lock used for internal testing
DI GES Internal Coordinates Global Enqueue Service deadlock detect
ion
RM GES Resource Remastering Coordinates Global Enqueue Service resource remast
ering
PE Parameter Synchronizes system parameter updates
PG Global Parameter Synchronizes global system parameter updates
FP File Object Synchronizes various File Object(FOB) operations
\- 리소스 테이블을 이용하여 Engueue 리소스 구조체를 관리함
\- 해싱 알고리즘을 사용하여 필요한 Resource를 찾음
\- 각 해시 버킷에는 리소스 구조체가 연결(linked list)되어 있음

1. A 세션이 Shared 모드로 Lock 획득한다.
2. B 세션이 Shared 모드로 Lock을 획득하려고 한다. 먼저 Lock을 소유한 A 세션과 호환되므로 정상적으로 Lock을 획득한다. 이제 소유자 목록에는 두 개 세션이 달려 있다.
3. C 세션이 Exclusive 모드로 Lock을 획득하려고 한다. Shared 모드와 Exclusive 모드 간에 호환성이 없으므로 대기자 목록에 자신을 등록하고 대기한다.
4. 소유자 목록에 Shared 모드로 달려 있던 A, B 두 세션이 모두 Lock을 해제하면 C 세션이 Exclusive 모드로 소유자 목록에 등록된다.
5. A 세션이 Exclusive 모드로 다시 Lock을 획득하려고 하면, Exclusive 모드와 호환되지 않으므로 대기자 목록에 자신을 등록하고 대기한다.
6. B 세션이 다시 Shared 모드로 Lock을 획득하려고 할 때도 Exclusive 모드와 호환되지 않으므로 대기자 목록에 자신을 등록하고 대기한다.
7. Enqueue Lock은 순서가 보장되므로 C 세션이 Lock을 해제하면 A 세션이 가장 먼저 Exclusive 모드로 Lock을 획득한다.
\- Transaction을 시작하려면 Undo Segment Header에 위치한 Transaction Table로 부터 Slot을 하나 할당 받아야 함
\- DML중 Seleclt 요청이 들어오면 CR블럭을 생성하여 읽음
\- DML중 DML 요청이 들어오면 TX Lock 매터니즘을 사용하여 Access 를 직렬화함
\- TX Lock은 Transaction이 첫번째 변경할 때 얻고, 커밋 또는 롤백시 해제됨

1. TX1 트랜젝션은 Undo 세그먼트에서 트랜젝션 슬롯을 할당받고, Enqueue 리소스를 통해 TX Lock을 설정
- TX Lock 경합 상황 모니터링 -
SQL> select sid, type, id1, id2, lmode, request, block
2 , to_char(trunc(id1/power(2,16))) USN
3 , bitand(id1, to_number('ffff', 'xxxx')) + 0 SLOT
4 , id2 SQN
5 from v$lock
6 where TYPE = 'TX' ;
SID TY ID1 ID2 LMODE REQUEST BLOCK USN SLOT SQN
----- -- -------- ----- ------- --------- ------- --- ------- -------
145 TX 655401 1601 0 6 0 10 41 1601
150 TX 655401 1601 6 0 1 10 41 1601

SQL> select sid, seq#, event, state, seconds_in_wait,
2 decode(to_char(bitand(p1, 65536)), 0, 'None', 1, 'Null', 2, 'RS', 3, 'RX', 4, 'S', 5, 'SRX', 6, 'X') "Lock_mode",
3 trunc(p2/power(2,16)) "USN",
bitand(p2, to_number('ffff', 'xxxx')) + 0 "SLOT",
4 p3 "tran_slot_seq"
5 from v$session_wait
6 where event like 'enq: TX%' ;
SID SEQ# EVENT STATE SECONDS_IN_WAIT Lock_mode USN SLOT tran_slot_seq
---------- ---------- ----------------------------------- ---------- --------------- --------------- ----- ---------- -------------
1087 109 enq: TX - row lock contention WAITING 5459 None 13 22 41
SQL> select * from tt01;
NO NAME
---------- --------------------
1 aaa
2 bbb
3 ccc
4 ddd
5 eee
6 fff
7 ggg
8 hhh
9 iii
10 jjj
SQL> insert into tt01 values (12,'lll'); --> TX1
1 row created.
SQL> insert into ksy1.tt01 values(12,'lll'); -->TX2
SQL> select sid, type, id1, id2, lmode, request, block
2 , to_char(trunc(id1/power(2,16))) USN
3 , bitand(id1, to_number('ffff', 'xxxx')) + 0 SLOT
4 , id2 SQN
5 from v$lock
6 where TYPE = 'TX' ;
SID TY ID1 ID2 LMODE REQUEST BLOCK USN SLOT SQN
---------- -- ---------- ---------- ---------- ---------- ---------- ---------------------------------------- ---- ----------
1086 TX 589829 227 0 4 0 9 5 227
1086 TX 851984 41 6 0 2 13 16 41
SQL> select sid, seq#, event, state, seconds_in_wait,
2 decode(to_char(bitand(p1, 65536)), 0, 'None', 1, 'Null', 2, 'RS', 3, 'RX', 4, 'S', 5, 'SRX', 6, 'X') "Lock_mode",
3 trunc(p2/power(2,16)) "USN",
4 bitand(p2, to_number('ffff', 'xxxx')) + 0 "SLOT",
5 p3 "tran_slot_seq"
6 from v$session_wait
7 where event like 'enq: TX%';
SID SEQ# EVENT STATE SECONDS_IN_WAIT Lock USN SLOT tran_slot_seq
---------- ---------- ---------------------------------------- --------------- --------------- ---- ---------- ---- -------------
1086 69 enq: TX - row lock contention WAITING 72 None 9 5 227
SQL> commit; --> TX1 Commit
SQL> insert into ksy1.tt01 values(12,'lll'); --> TX2에서 Error 발생
insert into ksy1.tt01 values(12,'lll')
*
ERROR at line 1:
ORA-00001: unique constraint (KSY1.PK_TT01) violated
SQL> select * from tt01; --> no 컬럼에 PK 설정
NO NAME
---------- ---------------
1 aaa
2 bbb
3 ccc
4 ddd
5 eee
6 fff
7 ggg
8 hhh
9 iii
10 jjj
11 kkk
12 lll
12 rows selected.
SQL> select * from tt02; --> no 컬럼에 FK 설정
NO TEL
---------- ----------
1 !!!
2 @@@
3 ###
4 $$$
5 %%%
6 ^^^
7 &&&
8 ***
9 (((
10 )))
11 !@#
11 rows selected.
SQL> delete from tt01 where no=12; -->TX1
1 row deleted.
SQL> insert into ksy1.tt02 values (12,'@#$'); -->TX2
SQL> select sid, type, id1, id2, lmode, request, block
2 , to_char(trunc(id1/power(2,16))) USN
3 , bitand(id1, to_number('ffff', 'xxxx')) + 0 SLOT
4 , id2 SQN
5 from v$lock
6 where TYPE = 'TX' ;
SID TY ID1 ID2 LMODE REQUEST BLOCK USN SLOT SQN
---------- -- ---------- ---------- ---------- ---------- ---------- ---------------------------------------- ---------- ----------
1069 TX 65573 241 0 4 0 1 37 241
1105 TX 65573 241 6 0 1 1 37 241
SQL> select sid, seq#, event, state, seconds_in_wait,
2 decode(to_char(bitand(p1, 65536)), 0, 'None', 1, 'Null', 2, 'RS', 3, 'RX', 4, 'S', 5, 'SRX', 6, 'X') "Lock_mode",
3 trunc(p2/power(2,16)) "USN",
4 bitand(p2, to_number('ffff', 'xxxx')) + 0 "SLOT",
5 p3 "tran_slot_seq"
6 from v$session_wait
7 where event like 'enq: TX%';
SID SEQ# EVENT STATE SECONDS_IN_WAIT Lock USN SLOT tran_slot_seq
---------- ---------- ----------------------------------- --------------- --------------- ---- ---------- ---------- -------------
1069 323 enq: TX - row lock contention WAITING 75 None 1 37 241
SQL> commit; --> TX1 Commit
SQL> insert into ksy1.tt02 values (12,'@#$'); --> TX2에서 Error 발생
insert into ksy1.tt02 values (12,'@#$')
*
ERROR at line 1:
ORA-02291: integrity constraint (KSY1.TT02_FK) violated - parent key not found
1. Shared 모드로 enq: TX - row lock contention 대기 이벤트가 발생할 수 있음
2. 비트맵 인덱스의 구조상 하나의 엔트리가 여러 개 레코드와 매핑되고, 하나의 엔트리에 Lock을 설정하면 매핑되는 레코드 전체에 Lock이 설정됨
3. 비트맵 인덱스 엔트리를 두 개 이상 트랜젝션이 동시에 갱신할 때 이 이벤트가 자주 발생
4. TX1 트랜젝션이 1번 레코드를 갱신하는 동안 TX2 트랜젝션이 2번 레코드를 갱신하려고 할 때 Shared 모드로 enq: TX - row lock contention 대기 이벤트가 발생
- Table의 INITRANS 재 설정 -
** 대상 Table에 Index가 있을 경우 모두 Unusable됨 **
SQL> select TABLE_NAME, PCT_FREE, INI_TRANS, MAX_TRANS from dba_tables where table_name='TT01';
TABLE_NAME PCT_FREE INI_TRANS MAX_TRANS
------------------------------ ---------- ---------- ----------
TT01 10 1 255
SQL> alter table tt01 move initrans 10;
Table altered.
SQL> select TABLE_NAME, PCT_FREE, INI_TRANS, MAX_TRANS from dba_tables where table_name='TT01';
TABLE_NAME PCT_FREE INI_TRANS MAX_TRANS
------------------------------ ---------- ---------- ----------
TT01 10 10 255
- Index의 INITRANS 재 설정 -
SQL> select TABLE_NAME, INDEX_NAME , PCT_FREE, INI_TRANS, MAX_TRANS from dba_indexes where table_name='TT01';
TABLE_NAME INDEX_NAME PCT_FREE INI_TRANS MAX_TRANS
------------------------------ ------------------------------ ---------- ---------- ----------
TT01 SYS_C003144 10 2 255
SQL> alter index ksy1.SYS_C003144 rebuild INITRANS 10;
Index altered.
SQL> select TABLE_NAME, INDEX_NAME , PCT_FREE, INI_TRANS, MAX_TRANS from dba_indexes where table_name='TT01';
TABLE_NAME INDEX_NAME PCT_FREE INI_TRANS MAX_TRANS
------------------------------ ------------------------------ ---------- ---------- ----------
TT01 SYS_C003144 10 10 255
\- 테이블에서의 PCTFREE는 나중에 발생할 UPDATE를 위한 공간
\- 인덱스에서의 PCTFREE는 Insert를 위한 공간
=> 인덱스 분할의 최소화 방안 : PCTFREE를 증가시키면 되나 일시적이므로, 인덱스를 주기적으로 재생성 하는것이 근본적인 해결책임

- RS(select for update), RX(insert,update,delete,merge) 간에 테이블 Lock 경합은 없으나, 로우 갱신때는 로우 Lock이 발생함
\* \* {*}select * from t for update \--> Lock 해제 될때 까지 기다림{*}
{*}lock table emp in exclusive mode NOWAIT; \--> lock table 명령어를 이용 해당 테이블에 옵션을 설정{*}
# commit_write 파라미터를 이용해 시스템 또는 세션 레벨에서 기본 설정을 변경 가능
SQL> show parameter commit
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
commit_point_strength integer 1
commit_write string
max_commit_propagation_delay integer 0
SQL> alter session set commit_write=batch,nowait;
Session altered.
SQL> show parameter commit
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
commit_point_strength integer 1
commit_write string BATCH, NOWAIT
max_commit_propagation_delay integer 0
create table t (a number) ;
begin
for item in 1..100000
loop
insert into t values(item);
commit write [immediate | batch] [wait | nowait];
end loop;
end;
/
COMMIT WRITE IMMEDIATE WAIT ; -- 68초
COMMIT WRITE IMMEDIATE NOWAIT ; -- 9초
COMMIT WRITE BATCH WAIT ; -- 66초
COMMIT WRITE BATCH NOWAIT ; -- 6초